package com.yang.service.Impl;

import com.yang.exception.BusinessException;
import com.yang.mapper.SysUserMapper;
import com.yang.pojo.SysUser;
import com.yang.service.LoginService;
import com.yang.utils.Constants;
import com.yang.utils.JsonResult;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Map;

/**
 * Created by 杨天可 on 2022/3/29 11:06
 */
@Service("loginService")
@Transactional
public class LoginServiceImpl implements LoginService {
    @Resource
    SysUserMapper sysUserMapper;

    @Override
    public Map<String,Object> userLogin(String phone, String password) {
        JsonResult jsonResult = new JsonResult();
        try {
            SysUser byUsername = sysUserMapper.findByPhone(phone);
            if (byUsername != null) {
                UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(phone,password);
                Subject subject = SecurityUtils.getSubject();
                subject.login(usernamePasswordToken);   //完成登录
                SysUser user = (SysUser) subject.getPrincipal();

                jsonResult.setCode(Constants.SUCCESS);
                jsonResult.setData(user);
                jsonResult.setMsg("登录成功");
            }
        }catch(UnknownAccountException uae){
            System.out.println("对用户[" + phone + "]进行登录验证..验证未通过,未知账户");
            throw new BusinessException("未知账户");
        }catch(IncorrectCredentialsException ice){
            System.out.println("对用户[" + phone + "]进行登录验证..验证未通过,错误的凭证");
            throw new BusinessException("密码不正确");
        }catch(LockedAccountException lae){
            System.out.println("对用户[" + phone + "]进行登录验证..验证未通过,账户已锁定");
            throw new BusinessException("账户已锁定");
        }catch(ExcessiveAttemptsException eae){
            System.out.println("对用户[" + phone + "]进行登录验证..验证未通过,错误次数过多");
            throw new BusinessException("用户名或密码错误次数过多");
        }catch(AuthenticationException ae){
            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
            System.out.println("对用户[" + phone + "]进行登录验证..验证未通过,堆栈轨迹如下");
            ae.printStackTrace();
            throw new BusinessException("用户名或密码不正确");
        }
        return jsonResult.getValues();
    }

    @Override
    public Map<String, Object> loginOut() {
        JsonResult jsonResult = new JsonResult();
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        jsonResult.setCode(Constants.SUCCESS);
        jsonResult.setMsg("退出成功");
        return jsonResult.getValues();
    }
}
